package apollo

import (
	"context"
	"fmt"
	"gitee.com/dennis-kk/service-box-go/util/config/source"
	"gitee.com/dennis-kk/service-box-go/util/errors"
	"strings"
	"time"
)

type (
	cfgKey struct{}

	configFormat map[string]bool

	Config struct {
		// Host apollo 地址
		Host string
		// AppId apollo appid
		AppId string
		// NameSpace apollo 命名空间
		NameSpace string
		// Cluster 集群名称
		Cluster string
		// Secret 密钥
		Secret string
		// Timeout 超时时间
		Timeout time.Duration
		// IsRetry 是否重试
		IsRetry bool
		// Auth 包头签名
		Auth HTTPAuth
		// ConfigExt 支持的配置扩展名
		ConfigExt configFormat
	}
)

func NewConfig() *Config {
	return &Config{
		NameSpace: "application",
		Cluster:   "default",
		IsRetry:   false,
		Auth:      &AuthSignature{},
		ConfigExt: configFormat{
			".yaml": true,
		},
	}
}

// Set 解析批量数据输入 按自定义规则设置到需要的字段
func (cfg *Config) Set(value string) error {
	params := strings.Split(value, " ")
	switch len(params) {
	case 5:
		// 设置 Secret 密钥
		cfg.Secret = params[4]
		fallthrough
	case 4:
		// 设置集群信息
		cfg.Cluster = params[3]
		fallthrough
	case 3:
		// 设置 Namespace
		cfg.NameSpace = params[2]
		fallthrough
	case 2:
		// 配置 appId 与 host 地址
		cfg.AppId = params[1]
		cfg.Host = params[0]
	default:
		return errors.InvalidApolloCfg
	}
	return nil
}

func (cfg *Config) String() string {
	return fmt.Sprintf("%s %s %s %s", cfg.Host, cfg.AppId, cfg.NameSpace, cfg.Cluster)
}

func WithApolloHost(cfg *Config) source.Option {
	return func(o *source.Options) {
		if o.Context == nil {
			o.Context = context.Background()
		}

		o.Context = context.WithValue(o.Context, cfgKey{}, cfg)
	}
}
